import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.LineBorder;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;

import javax.swing.JTextPane;

import Environment.*;
import GUIPanels.*;
import Population.Inhabitant;
import Tests.*;
import World.World;


public class Main {
	
	
	
	WorldPanel wPanel;
	PeoplePanel pPanel;
	HUDPanel hudPanel;
	
	//public MyCanvas myCanvas;
	//public WorldCanvas worldCanvas;
	public static World myWorld;
	Timer timer;
	int RandomNum;//500;//8
	int CellSize = 45;//65;//5;//3
	int speed = 1000/60;
	int numPop =25;
	
	boolean debug = false;
	
	private JFrame frame;
	
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {

					

					Main window = new Main();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public Main() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {	
		
		frame = new JFrame();
		frame.setBounds(100, 100, 727, 572);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);
		
		final JTextPane txtOutput = new JTextPane();
		txtOutput.setBounds(10, 447, 337, 76);
		frame.getContentPane().add(txtOutput);
		
		JPanel panelWorld = new JPanel();
		panelWorld.setBorder(new LineBorder(new Color(0, 0, 0)));
		panelWorld.setBounds(10, 11, 691, 391);
		//frame.getContentPane().add(panelWorld);
		
		pPanel = new PeoplePanel();
		pPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
		pPanel.setBounds(10, 11, 691, 391);
		pPanel.setOpaque(true);
		
		wPanel = new WorldPanel();
		wPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
		wPanel.setBounds(10, 11, 691, 391);
		wPanel.setOpaque(true);
		
		hudPanel = new HUDPanel();
		hudPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
		hudPanel.setBounds(10, 11, 691, 391);
		hudPanel.setOpaque(true);
		
		final JButton btnStart = new JButton("Start");
		btnStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(timer.isRunning())
				{
					timer.stop();
					btnStart.setText("Start");
				}
				else
				{
					timer.start();
					btnStart.setText("Stop");
				}
			}
		});
		btnStart.setBounds(217, 413, 89, 23);
		frame.getContentPane().add(btnStart);
		
		JButton btnReset = new JButton("Reset");
		btnReset.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(World.PrintToOutFile)
					try {
						World.outFile = new PrintStream(new File("C:\\Users\\ll87\\workspace2\\BusinessTime\\Output.txt"));
					} catch (FileNotFoundException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				myWorld = new World(pPanel.getWidth(),pPanel.getHeight(), RandomNum, CellSize, numPop);
				//worldCanvas.repaint();
				//myCanvas.repaint();
				wPanel.repaint();
				pPanel.repaint();
				pPanel.repaint();
				hudPanel.repaint();
				
			}
		});
		btnReset.setBounds(415, 413, 89, 23);
		frame.getContentPane().add(btnReset);
		
		JButton btnStep = new JButton("Step");
		btnStep.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(timer.isRunning() == false)
				{
					World.Update();
					//myCanvas.repaint();
					pPanel.repaint();
					hudPanel.repaint();
				}
			}
		});
		btnStep.setBounds(316, 413, 89, 23);
		frame.getContentPane().add(btnStep);
		
		final JTextPane textEnviron = new JTextPane();
		textEnviron.setBounds(357, 447, 344, 76);
		frame.getContentPane().add(textEnviron);

		pPanel.addMouseListener(new MouseListener(){

			@Override
			public void mouseClicked(MouseEvent arg0) {
				int x = (int)arg0.getX()/World.cellSize;
				int y = (int)arg0.getY()/World.cellSize;
				if(x<World.environGrid[0].length && y<World.environGrid.length){
					Environment tempEnviron = World.environGrid[y][x];
					Inhabitant sample = myWorld.FindInhabitant(x, y);
					
					if(sample.getX() != -1)
					{
						txtOutput.setText("Cell:"+sample.getType() + "\n"+
										  "Position:"+sample.getX()+","+sample.getY()+"\n"+
										  "isAlive:"+sample.getLife()+"\n"
										  );
					}
					else
					{
						txtOutput.setText("Loc:"+x+","+y+"\n"
								  );
					}
					textEnviron.setText("Name:"+tempEnviron.name+"\n"+
									  	"Food:"+tempEnviron.foodCount+"\n"+
										"Habitable:"+tempEnviron.isHabitable+"\n"+
										"Distance to Water:"+myWorld.DistanceToEnvironment(x,y,"Water")+"\n"+
										"Similar:"+myWorld.FindSimilar(World.environGrid, y, x, tempEnviron.name)
										);
				}
				else
				{
					txtOutput.setText("Out of Bounds.");
					textEnviron.setText("");
				}
			}

			@Override
			public void mouseEntered(MouseEvent arg0) {
			}

			@Override
			public void mouseExited(MouseEvent arg0) {
			}

			@Override
			public void mousePressed(MouseEvent arg0) {
			}

			@Override
			public void mouseReleased(MouseEvent arg0) {
			}
			
		});
		
		
		pPanel.addKeyListener(new KeyListener(){

			@Override
			public void keyPressed(KeyEvent arg0) {
			}

			@Override
			public void keyReleased(KeyEvent arg0) {
				// TODO Auto-generated method stub
				if(arg0.isControlDown() && arg0.getKeyCode()==KeyEvent.VK_Q)
				{
					System.exit(0);
				}
				else if(arg0.isControlDown() && arg0.getKeyCode()==KeyEvent.VK_S)
				{
					if(timer.isRunning())
					{
						timer.stop();
						btnStart.setText("Start");
					}
					else
					{
						timer.start();
						btnStart.setText("Stop");
					}
				}
				else if(arg0.isControlDown() && arg0.getKeyCode()==KeyEvent.VK_R)
				{
					hudPanel.Alert("Loading New Map.  Please Wait..");
					myWorld = new World(pPanel.getWidth(),pPanel.getHeight(), RandomNum, CellSize, numPop);
					
					wPanel.repaint();
					pPanel.repaint();
					hudPanel.repaint();
					
				}
				else if(!arg0.isControlDown() && arg0.getKeyCode()==KeyEvent.VK_S)
				{
					if(timer.isRunning() == false)
					{
						World.Update();
						pPanel.repaint();
						hudPanel.repaint();

					}
				}
			}

			@Override
			public void keyTyped(KeyEvent arg0) {
			}
			
		});
		
		RandomNum = (pPanel.getWidth() * pPanel.getHeight())/(numPop*numPop);
		//System.out.println(worldCanvas.getWidth()+","+worldCanvas.getHeight()+","+RandomNum);
		myWorld = new World(pPanel.getWidth(),pPanel.getHeight(), RandomNum, CellSize, numPop);
		
		panelWorld.setBackground(Color.black);
		
		frame.getContentPane().add(hudPanel);
		frame.getContentPane().add(pPanel);   // LESSON LEARNED.. Never Again CANVAS!!!
		frame.getContentPane().add(wPanel);
		
		pPanel.repaint();
		wPanel.repaint();
		hudPanel.repaint();
			
		ActionListener taskPerformer = new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				//...Perform a task...
				World.Update();
				pPanel.repaint();
				hudPanel.repaint();
				System.gc();
				if(World.pop.getLength() == 0)
				{
					timer.stop();
					btnStart.setText("Start");
				}
			}
		};
		timer = new Timer(speed, taskPerformer);
		
		if (debug)
		{
			/************ RUN TESTS ***************/
			
			TestFriends t1 = new TestFriends();
			if(t1.Test())
			{
				System.out.println("TestFriends = True");
			}
			else
			{
				String s = "";
				for (int i =0; i<t1.getTests().length; i++)
				{
					s = s +t1.getTests()[i]+"\n";
				}
				System.out.println(s);
			}
			
			System.out.println("----------------------------------");
			
			TestGroupSize t2 = new TestGroupSize();
			if(t2.Test())
			{
				System.out.println("TestGroupSize = True");
			}
			else
			{
				String s = "";
				for (int i =0; i<t2.getTests().length; i++)
				{
					s = s +t2.getTests()[i]+"\n";
				}
				System.out.println(s);
			}
			
			System.out.println("----------------------------------");
		}
	}

}
